package com.hornsun.authorization.api;

import com.hornsun.authorization.dto.AccountQueryDTO;
import com.hornsun.authorization.dto.AuthInfoDTO;
import com.hornsun.authorization.service.AuthorizationService;
import com.hornsun.config.ConfigInfo;
import com.hornsun.config.IRedisService;
import com.hornsun.data.constant.error.AuthError;
import com.hornsun.data.constant.types.Whether;
import com.hornsun.data.dbo.*;
import com.hornsun.data.repository.*;
import com.hornsun.data.repository.mapper.AuthInfoMapper;
import com.hornsun.util.SerializeUtils;
import com.hornsun.util.StrUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;

/**
 * Created by 编译中... on 2018/7/8.
 */
@RestController
@RequestMapping("/api/auth")
public class AuthorizationAPI {

    @Autowired
    private AuthorizationService authorizationService;

    @Autowired
    private AuthorizationRepository authorizationRepository;

    @Autowired
    private ClientRepository clientRepository;

    @Autowired
    private AuthInfoMapper authInfoMapper;

    @Autowired
    private RoleRepository roleRepository;

    @Autowired
    private ConfigInfo configInfo;

    @Autowired
    private SysinfoRepository sysinfoRepository;

    @Autowired
    private IRedisService service;


    @GetMapping("/getAuthInfo")
    public ResponseEntity<AuthInfoDTO> getAuthInfo(@RequestParam("page")int page) throws Exception {
        AuthInfoDTO authInfoDTO = new AuthInfoDTO();
        authInfoDTO.setAuthClientList(authorizationService.getAuthClientDTO(page));
        authInfoDTO.setAuthCount(authorizationRepository.getTotalCount());
        authInfoDTO.setTotalAuth(sysinfoRepository.getAuthPoint());
        return new ResponseEntity<AuthInfoDTO>(authInfoDTO, HttpStatus.OK);
    }

    @GetMapping("/getTotalRole")
    public ResponseEntity<?> getTotalRole(){
        return new ResponseEntity<Object>(roleRepository.getTotalRole(),HttpStatus.OK);
    }


    @Transactional
    @PostMapping("/permission/authorization")
    public ResponseEntity<?> authorization(@RequestParam("guid")String clientGuid,@RequestParam("days")int days) throws Exception {
        Sysinfo sysinfo = sysinfoRepository.getSysinfo();
        if (authorizationRepository.getTotalCount()>=sysinfoRepository.getAuthPoint()){
            return new ResponseEntity<Object>(AuthError.AUTH_COUNT_LIMIT.getCode(),HttpStatus.OK);
        }
        if (days>configInfo.getMaxOfflineDays()){
            return new ResponseEntity<Object>(AuthError.MAX_OFFLINE_DAYS_LIMIT.getCode(),HttpStatus.OK);
        }
        if (authorizationService.hasAuth(clientGuid)){
            return new ResponseEntity<Object>(AuthError.UNABLE_REPEAT_AUTH.getCode(),HttpStatus.OK);
        }
        Authorization authorization = new Authorization();
        authorization.setClientGuid(clientGuid);
        authorization.setAuthApp(sysinfo.getApp());
        authorization.setAuthQuota(sysinfo.getQuota());
        authorization.setOfflineTime(StrUtil.dayToMinute(days));
        authorization.setPointsForlogin(1);
        authorization.setValidityTime(-1);
        authorization.setTime(new Date());
        authorizationRepository.add(authorization);
        Client client = new Client();
        client.setClientGuid(clientGuid);
        client.setWhetherAuth((byte) Whether.YES.getType().intValue());
        clientRepository.updateClient(client);
        return new ResponseEntity<Object>(HttpStatus.OK);
    }

    @Transactional
    @PostMapping("/permission/delete")
    public ResponseEntity<?> delete(String[] guids){
        if (guids==null){
            return new ResponseEntity<Object>(HttpStatus.OK);
        }
        int failed=0;
        for (int i=0;i<guids.length;i++){
            Client client = clientRepository.getByGuid(guids[i]);
            if (client==null){
                failed++;
                continue;
            }
            Authorization authorization = authorizationRepository.getByGuid(client.getClientGuid());
            if ((authorization.getOfflineTime()>0)&&service.isKeyExists(configInfo.getRedisAccount(),client.getAccount())){
                byte[] clientInfoBytes = (byte[]) service.get(configInfo.getRedisAccount(),client.getAccount());
                ClientInfo clientInfo = (ClientInfo) SerializeUtils.deSerialize(clientInfoBytes);
                if (clientInfo!=null){
                    List<OfflineInfo> offlineInfoList = clientInfo.getOfflineInfoList();
                    List<AccountInfo> accountInfoList = clientInfo.getAccountInfoList();
                    if (offlineInfoList.size()!=0){
                        failed++;
                        continue;
                    }
                    if (accountInfoList.size()!=0){
                        Date now = new Date();
                        if (now.getTime()-accountInfoList.get(0).getTime().getTime()>12*1000){
                            failed++;
                            continue;
                        }
                    }
                }
            }
            service.remove(configInfo.getRedisAccount(),client.getAccount());
            authorizationRepository.delete(guids[i]);
            Client newClient = new Client();
            newClient.setClientGuid(guids[i]);
            newClient.setWhetherAuth((byte)Whether.NOT.getType().intValue());
            clientRepository.updateClient(newClient);
            }

        return new ResponseEntity<Object>(failed,HttpStatus.OK);
    }

    @PostMapping("/permission/updateOfflineTime")
    public ResponseEntity<?> updateOfflineTime(@RequestParam("guid")String guid,@RequestParam("days")Integer days){
        if (days>configInfo.getMaxOfflineDays()){
            return new ResponseEntity<Object>(AuthError.MAX_OFFLINE_DAYS_LIMIT.getCode(),HttpStatus.OK);
        }
        Authorization authorization = new Authorization();
        authorization.setClientGuid(guid);
        authorization.setOfflineTime(StrUtil.dayToMinute(days));
        authorizationRepository.updateOfflineTime(authorization);
        return new ResponseEntity<String>(HttpStatus.OK);
    }

    @GetMapping("/query")
    public ResponseEntity<?> query(@RequestParam("content")String content,@RequestParam("page")int page){
        String account = "%"+content+"%";
        AccountQueryDTO accountQueryDTO = new AccountQueryDTO();
        accountQueryDTO.setAuthClientList(authInfoMapper.getByAccount(account,(page-1)*10,10));
        accountQueryDTO.setCount(authInfoMapper.getCountByAccount(account));
        return new ResponseEntity<Object>(accountQueryDTO,HttpStatus.OK);
    }




}
